# +----------------------------------------------------------------------
# | ChatWork智能聊天办公系统
# +----------------------------------------------------------------------
# | 软件声明: 本系统并非自由软件,未经授权任何形式的商业使用均属非法。
# | 版权保护: 任何企业和个人不允许对程序代码以任何形式任何目的复制/分发。
# | 授权要求: 如有商业使用需求,请务必先与版权所有者取得联系并获得正式授权。
# +----------------------------------------------------------------------
# | Author: ChatWork Team <2474369941@qq.com>
# +----------------------------------------------------------------------
import time
from tortoise.queryset import Q

from common.enums.notice import NoticeEnum
from common.utils.urls import UrlUtil
from common.models.users import UserModel
from common.models.auth import AuthAdminModel
from common.models.video import VideoSquareModel
from common.models.public import SquareCategoryModel
from apps.admin.schemas.square import video_schema as schema
from plugins.msg.driver import MsgDriver


class SquareVideoService:

    @classmethod
    async def lists(cls, params: schema.SquareVideoSearchIn):
        where = VideoSquareModel.build_search({
            "%like%": ["prompt"],
            "=": ["is_enable", "audit_status", "cate_id"],
            "datetime": ["start_time|end_time@create_time"]
        }, params.__dict__)

        where.append(Q(is_delete=0))
        if params.user:
            condition = [Q(sn=params.user)]
            users = await UserModel.filter(*condition).filter(is_delete=0).limit(510).values("id")
            ids = [int(item["id"]) for item in users] or [0]
            where.append(Q(user_id__in=ids))

        _model = VideoSquareModel.filter(*where).order_by("-id")
        _pager = await VideoSquareModel.paginate(
            model=_model,
            page_no=params.page_no,
            page_size=params.page_size,
            fields=VideoSquareModel.without_field(str("is_delete,delete_time"))
        )

        # 查询分类
        cate_ids = [item["cate_id"] for item in _pager.lists]
        category = await SquareCategoryModel.queryCateDictsById(cate_ids)

        # 查询管理
        admin_ids = [item["operate_id"] for item in _pager.lists if item["source"] == 1]
        admins = await AuthAdminModel.queryAdminDictsById(admin_ids)

        # 查询用户
        user_ids = [item["operate_id"] for item in _pager.lists if item["source"] == 2]
        users = await UserModel.queryUserDictsById(user_ids)

        _lists = []
        for item in _pager.lists:
            cate = category.get(item["cate_id"]) or {}
            if item["source"] == 2:
                user = users.get(item["operate_id"]) or {}
            else:
                user = admins.get(item["operate_id"]) or {}

            _lists.append(schema.SquareVideoListVo(
                id=item["id"],
                cate_id=item["cate_id"],
                category=cate.get("name", "-"),
                video_code=item.get("video_code", ""),
                video_url=await UrlUtil.to_absolute_url(item.get("video_url")),
                prompt=item["prompt"],
                sort=item["sort"],
                source=item["source"],
                public_sum=item["public_sum"],
                audit_result=item["audit_result"],
                audit_status=item["audit_status"],
                is_enable=item["is_enable"],
                create_time=item["create_time"],
                update_time=item["update_time"],
                user={
                    "sn": user.get("sn", "").strip(),
                    "nickname": user.get("nickname", ""),
                    "mobile": user.get("mobile", ""),
                    "avatar": await UrlUtil.to_absolute_url(user.get("avatar", ""))
                }
            ))

        _pager.lists = _lists
        return _pager

    @classmethod
    async def audit(cls, post: schema.SquareVideoAuditIn):
        await VideoSquareModel.filter(id=post.id).filter(is_delete=0).get()
        await VideoSquareModel.filter(id=post.id).update(
            audit_result=post.audit_result,
            audit_status=post.audit_status,
            update_time=int(time.time())
        )

    @classmethod
    async def edit(cls, post: schema.SquareVideoEditIn):
        await VideoSquareModel.filter(id=post.id).filter(is_delete=0).get()
        await VideoSquareModel.filter(id=post.id).update(
            cate_id=post.cate_id,
            sort=post.sort,
            is_enable=post.is_enable,
            update_time=int(time.time())
        )

    @classmethod
    async def delete(cls, id_: int, reason: str):
        record = await VideoSquareModel.filter(id=id_, is_delete=0).get()
        await VideoSquareModel.filter(id=id_).update(
            is_delete=0,
            delete_time=int(time.time())
        )

        # 发送用户通知
        if record.source == 2:
            await MsgDriver.send(scene=NoticeEnum.SQUARE_VIDEO_DELETE, params={
                "user_id": record.operate_id,
                "code": record.video_code,
                "prompt": record.prompt,
                "reason": reason
            })

    @classmethod
    async def disable(cls, id_: int, reason: str):
        """
        视频广场禁显。

        Args:
            id_ (int): 广场ID。
            reason (str): 原因信息。

        Author:
            zero
        """
        # 查找记录
        record = await VideoSquareModel.filter(id=int(id_), is_delete=0).get()

        # 调整状态值
        status = 0 if record.is_enable else 1
        await VideoSquareModel.filter(id=id_, is_delete=0).update(
            is_enable=status,
            update_time=int(time.time())
        )

        # 发送用户通知
        if record.source == 2:
            scene = NoticeEnum.SQUARE_VIDEO_SHOW if status == 1 else NoticeEnum.SQUARE_VIDEO_HIDDEN
            await MsgDriver.send(scene=scene, params={
                "user_id": record.operate_id,
                "code": record.video_code,
                "prompt": record.prompt,
                "reason": reason or "-"
            })

